package com.yqg.education.common.interceptor;

import com.yqg.education.entity.OperateRecord;
import com.yqg.education.service.IOperateRecordService;
import com.yqg.education.utils.IPUtils;
import com.yqg.education.utils.JwtTokenUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * 系统日志，切面处理类
 */
@Aspect
@Component
public class SysLogAspect {

    private final JwtTokenUtil jwtTokenUtil;

    private final IPUtils ipUtils;

    @Autowired
    private IOperateRecordService operateRecordService;

    public SysLogAspect(JwtTokenUtil jwtTokenUtil, IPUtils ipUtils) {
        this.jwtTokenUtil = jwtTokenUtil;
        this.ipUtils = ipUtils;
    }

    //切点就是被SysLog注释的方法
    @Pointcut("@annotation(com.yqg.education.common.interceptor.SysLog)")
    public void logPointCut() {

    }

    //方法执行前后都操作
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        //执行方法
        Object result = point.proceed();
        //保存日志
        saveSysLog(point);
        return result;
    }

    private void saveSysLog(ProceedingJoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        OperateRecord operateRecord = new OperateRecord();
        SysLog syslog = method.getAnnotation(SysLog.class);
        if (syslog != null) {
            //注解上的描述
            operateRecord.setContent(syslog.value());
        }

        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        operateRecord.setOperateType(className + "." + methodName + "()");

//        //请求的参数
//        Object[] args = joinPoint.getArgs();
//        try {
//            String params = new Gson().toJson(args);
//            recordOperate.setParams(params);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //设置IP地址
        operateRecord.setUserIp(ipUtils.getIpAddr(request));
        //用户名
        String token = request.getHeader("token");
        Long userId = jwtTokenUtil.getValueFormClaims(token, "UserId", Long.class);
        operateRecord.setUserId(userId);
        operateRecord.setCreatedTime(LocalDateTime.now());
        operateRecord.setIsDelete(0);
        //保存系统日志
        operateRecordService.save(operateRecord);
    }
}
